<?php

namespace tmcore\services\upload\driver;

use tmcore\exceptions\UploadException;
use tmcore\services\upload\BaseUpload;
use think\facade\Filesystem;

/**
 * 本地存储
 */
class Local extends BaseUpload
{
    /**
     * 上传文件
     * @param string $name 文件对象 name
     * @param array $rule 上传规则 ['fileSize' => 0, 'fileExt' => 'jpg']
     * @param string $file_type 文件类型
     * @return array
     * @throws UploadException
     */
    public function upload(string $name, array $rule, string $file_type = 'image') {

        try {
            //接受文件
            $file = $this->getFileInfo($name);
            //验证文件
            $this->validate($name, $rule);
        } catch (UploadException $e) {
            throw new UploadException($e->getMessage());
        }

        // 文件存放目录名称
        $dirname  = $this->getSavePath($file_type);

        // 存放文件
        $saveName = Filesystem::putFileAs($dirname, $file, $this->fileInfo['fileName']);
        if(!$saveName) throw new UploadException("文件上传本地失败");

        if($this->isFullPath) {
            // 完整路径
            $saveName = request()->domain(). '/' . $saveName;
        }

        $this->fileInfo['url'] = $saveName;
        // 上传文件信息
        return $this->fileInfo;
    }

    /**
     * 远程文件下载存储
     * @param string $url 文件路径
     * @param string $file_type 文件类型 image-图片 file-文件
     * @return array
     * @throws UploadException
     */
    public function fetch(string $url, string $file_type = 'image') {

        // 文件存放目录名称
        $dirname  = $this->getSavePath($file_type);
        if($dirname && $dirname != '/' && !file_exists(app()->getRootPath() . 'public/' . $dirname))mkdir(app()->getRootPath() . 'public/' . $dirname);

        $ext = $this->getFileExt($url);

        $file_name = $this->buildSaveName($ext);

        $savePath = $dirname . '/' . $file_name;

        $file_content = file_get_contents($url);;

        $result = file_put_contents(app()->getRootPath() . 'public/' . $savePath, $file_content);
        if(!$result) throw new UploadException("文件上传本地失败");

        return [
            'ext'          => $ext,
            'size'         => $result,
            'md5'          => '',
            'sha1'         => '',
            'originalName' => preg_replace('/^.+[\\\\\\/]/', '', $url),
            'fileName'     => $file_name,
            'url'          => ($this->isFullPath? request()->domain() . '/':'') . $savePath
        ];
    }

    /**
     * 批量上传文件
     * @param string $name 文件对象 name
     * @param array $rule 上传规则 ['fileSize' => 0, 'fileExt' => 'jpg', 'image' => '200,200,jpg']
     * @param string $file_type 文件类型 image-图片 file-文件
     * @return array
     * @throws UploadException
     */
    public function batchUpload(string $name, array $rule, string $file_type = 'image') {

        try {
            //接受文件
            $files = $this->getFileInfo($name, true);
            //循环检验
            foreach($files as $file) {
                $this->validate($name, $rule, $file);
            }
        } catch (UploadException $e) {
            throw new UploadException($e->getMessage());
        }

        // 文件存放目录名称
        $dirname  = $this->getSavePath($file_type);

        foreach($files as $key => $file) {
            $saveName = Filesystem::putFileAs($dirname, $file, $this->fileInfo[$key]['fileName']);
            if(!$saveName) throw new UploadException("文件上传本地失败");

            if($this->isFullPath) {
                // 完整路径
                $saveName = request()->domain(). '/' . $saveName;
            }
            $this->fileInfo[$key]['url'] = $saveName;
        }

        return $this->fileInfo;
    }

    /**
     * 删除文件
     * @param string $path 文件路径
     * @return bool
     * @throws UploadException
     */
    public function delete(string $path) {
        if(file_exists($path)){
            return unlink($path);
        }else{
            throw new UploadException("文件路径不存在");
        }
    }

}